///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef __BUOLA_IO_CRESOURCEFINDER_H__
#define __BUOLA_IO_CRESOURCEFINDER_H__

#include <buola/buola.h>
#include <buola/io/curi.h>

namespace buola { namespace io {

///\addtogroup io
///@{

////////////////////////////////////////////////////////////////////////////

/// helper class to find configuration and data files

/// it implements the XDG base directory specification to help applications
/// find system-wide and user-specific configuration files, as specified in
/// other specifications
///
/// besides being able to find files relative to one of the paths in the
/// specification, it can be extended with the concept of object types,
/// which specify possible extensions and paths to be added to the name, to
/// be able to easily locate different kinds of objects
///
////////////////////////////////////////////////////////////////////////////

class CResourceFinder
{
public:
    //!specifies the scope of a path
    enum EScope
    {
        SCOPE_USER,     //!< user-specific files
        SCOPE_SYSTEM    //!< system-wide files
    };

    enum EOptions
    {
        OPTION_NONE=0,
        CREATE=(1<<0),                  //!< create if doesn't exist
        MAYBE_ABSOLUTE=(1<<1),          //!< the provided name may be an absolute path
        USER_ONLY=(1<<2)                //!< search only in user paths
    };

    DECLARE_FRIEND_ENUM_BITOPS(EOptions)

private:
    struct SPath
    {
        EScope mScope;
        io::CURI mPath;
    };

public:
//! \name constructor and destructor
//@{
    CResourceFinder();
    CResourceFinder(const CResourceFinder &pBase,const std::vector<std::string> &pSubPaths);
    ~CResourceFinder();
//@}

//! \name path and type set-up
//@{
public:
    void AddPath(EScope pScope,const io::CURI &pPath);
    void AddExtension(const std::string &pExtension);
//@}

//! \name query interface
//@{
public:
    std::vector<io::CURI> FindFolders(const std::string &pName,EOptions=OPTION_NONE);
    io::CURI FindFolder(const std::string &pName,EOptions=OPTION_NONE);
    std::vector<io::CURI> FindFiles(const std::string&,EOptions=OPTION_NONE);
    io::CURI FindFile(const std::string&,EOptions=OPTION_NONE);
//@}

private:
    std::vector<SPath> mPaths;
    std::vector<std::string> mExtensions;
};

///\name Finding resources
//@{

///returns a CResourceFinder which can be used to find items in the data locations, as described in the XDG base
///directory specification
CResourceFinder &data_finder();

///returns a CResourceFinder which can be used to find items in the config locations, as described in the XDG base
///directory specification
CResourceFinder &config_finder();

///returns a CResourceFinder which can be used to find items in the cache locations, as described in the XDG base
///directory specification
CResourceFinder &cache_finder();

///returns a finder object to find mime types
CResourceFinder &mime_finder();

///returns a finder object to find icon resources
CResourceFinder &icon_finder();

///returns a finder object to find registry resources
CResourceFinder &registry_finder();

//@}

///@}

/*namespace io*/ } /*namespace buola*/ }

#endif
